﻿#include<iostream>
//using namespace std;
//// 1、参数类型不同
//
//int Add(int left, int right)
//{
//	cout << "int Add(int left, int right)" << endl;
//	return left + right;
//}
//double Add(double left, double right)
//{
//	cout << "double Add(double left, double right)" << endl;
//	return left + right;
//}
//// 2、参数个数不同
//
//void f()
//{
//	cout << "f()" << endl;
//}
//void f(int a)
//{
//	cout << "f(int a)" << endl;
//}
//// 3
//void f(int a, char b)
//{
//	cout << "f(int a,char b)" << endl;
//}
//void f(char b, int a)
//{
//	cout << "f(char b, int a)" << endl;
//}
//
//
//
//
//int main()
//{
//	Add(10, 20);
//	Add(10.1, 20.2);
//	f();
//	f(10);
//	f(10, 'a');
//	f('a', 10);
//	return 0;
//}
//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 0;
//	// 引⽤：	b和	c是a的别名
//
//		int& b = a;
//	    int& c = a;
//	// 也可以给别名	b	取别名，	d	相当于还是	a	的别名
//		int& d = b;
//	    ++d;
//	// 这⾥取地址我们看到是⼀样的
//
//		cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << &d << endl;
//	return 0;
//}
#include<iostream>
using namespace std;
//int main()
//{
//	int a = 10;
//	// 编译报错：“ra” :必须初始化引⽤
//
//		//int& ra;
//		int& b = a;
//	    int c = 20;
//	    b = c;
//	// 这⾥并⾮让b引⽤c，因为C++引⽤不能改变指向，
//		// 这⾥是⼀个赋值
//
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	return 0;
//}
//void Swap(int& rx, int& ry)
//{
//	int tmp = rx;
//	rx = ry;
//	ry = tmp;
//}
//int main()
//{
//	int x = 0, y = 1;
//	cout << x << " " << y << endl;
//	Swap(x, y);
//	cout << x << " " << y << endl;
//	return 0;
//}
//#include<iostream>
//using namespace std;
//typedef int STDataType;
//typedef struct Stack
//{
//	STDataType* a;
//	int top;
//	int capacity;
//}ST;
//void STInit(ST& rs, int n = 4)
//{
//	rs.a = (STDataType*)malloc(n * sizeof(STDataType));
//	rs.top = 0;
//	rs.capacity = n;
//}
//// 栈顶
//
//void STPush(ST& rs, STDataType x)
//{
//	//assert(ps);
//	// 满了，扩容
//
//		if (rs.top == rs.capacity)
//		{
//			printf("扩容\n");
//				int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;
//			STDataType * tmp = (STDataType*)realloc(rs.a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			rs.a = tmp;
//			rs.capacity = newcapacity;
//		}
//	rs.a[rs.top] = x;
//	rs.top++;
//}
//// int STTop(ST& rs)
//int& STTop(ST& rs)
//{
//	//assert(rs.top > 0);
//	return rs.a[rs.top];
//}
//int main()
//{
//	// 调⽤全局的
//
//		ST st1;
//	STInit(st1);
//	STPush(st1, 1);
//	STPush(st1, 2);
//	cout << STTop(st1) << endl;
//	STTop(st1) += 10;
//	cout << STTop(st1) << endl;
//	return 0;
//}

//#include<iostream>
//using namespace std;
//typedef struct SeqList
//{
//	int a[10];
//	int size;
//}SLT;
//// ⼀些主要⽤C代码实现版本数据结构教材中，使⽤C++引⽤替代指针传参，⽬的是简化程序，避开复杂的指针，但是很多同学没学过引⽤，导致⼀头雾⽔。
//
//void SeqPushBack(SLT & sl, int x)
//{
//}
//typedef struct ListNode
//{
//	int val;
//	struct ListNode* next;
//}LTNode, * PNode;
//// 指针变量也可以取别名，这⾥LTNode*& phead就是给指针变量取别名
//
//// 这样就不需要⽤⼆级指针了，相对⽽⾔简化了程序
//
////void ListPushBack(LTNode** phead, int x)
// //void ListPushBack(LTNode*& phead, int x)
//void ListPushBack(PNode& phead, int x)
//{
//	PNode newnode = (PNode)malloc(sizeof(LTNode));
//	newnode->val = x;
//	newnode->next = NULL;
//	if (phead == NULL)
//	{
//		phead = newnode;
//	}
//	else
//	{
//	}
//}
//int main()
//{
//	PNode plist = NULL;
//	ListPushBack(plist, 1);
//	return 0;
//}
//int main()
//{
//	const int a = 10;
//	// 编译报错：error C2440 : “初始化” :⽆法从“const int”转换为“int& ”
//		// 这⾥的引⽤是对a访问权限的放⼤
//
//		//int& ra = a;
//		 // 这样才可以
//
//		const int& ra = a;
//	// 编译报错：	error C3892 : “ra”:不能给常量赋值
//
//		//ra++;
//		 // 这⾥的引⽤是对b访问权限的缩⼩
//
//		//rb++;
//		int b = 20;
//	    const int& rb = b;
//	// 编译报错：	error C3892 : “rb”:不能给常量赋值
//
//		return 0;
//}
//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 10;
//	const int& ra = 30;
//	// 	编译报错	: “	初始化	” :⽆法从“int”转换为“int& ”
//		// int& rb = a * 3;
//		const int& rb = a * 3;
//	    double d = 12.34;
//	// 编译报错：	“初始化” :⽆法从“double”转换为“int& ”
//		// int& rd = d;
//		const int& rd = d;
//	return 0;
//}
//#include<iostream>
//using namespace std;
//inline int Add(int x, int y)
//{
//	int ret = x + y;
//	ret += 1;
//	ret += 1;
//	ret += 1;
//	return ret;
//}
//int main()
//{
//	// 可以通过汇编观察程序是否展开
//
//		// 有call Add语句就是没有展开，没有就是展开了
//
//	int ret = Add(1, 2);
//	cout << Add(1, 2) * 5 << endl;
//	return 0;
//}
#include<iostream>
using namespace std;
// 
实现⼀个
ADD
宏函数的常⻅问题

//#define ADD(int a, int b) return a + b;
 //#define ADD(a, b) a + b;
 //#define ADD(a, b) (a + b)
// // 
//	正确的宏实现
//
//#define ADD(a, b) ((a) + (b))
//	// 为什么不能加分号?
//	// 为什么要加外⾯的括号?
//	// // 为什么要加⾥⾯的括号?
//int main()
//{
//	int ret = ADD(1, 2);
//	cout << ADD(1, 2) << endl;
//	cout << ADD(1, 2) * 5 << endl;
//	int x = 1, y = 2;
//	ADD(x & y, x | y);  // -> (x&y+x|y)
//	return 0;
//}
//#ifndef NULL
//#ifdef __cplusplus
//#define NULL    
//#else
//#define NULL    
//#endif
//#endif

#include<iostream>
using namespace std;
void f(int x)
{
	cout << "f(int x)" << endl;
}
void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}
int main()
{
	f(0);
	// 本想通过	f(NULL)调⽤指针版本的	f(int*)	函数，但是由于	NULL	被定义成	0	，调⽤了f(intx)	，因此与程序的初衷相悖。f(NULL);
	f((int*)NULL);
	// 编译报错：	error C2665 : “f”: 2个重载中没有⼀个可以转换所有参数类型

		// f((void*)NULL);
		f(nullptr);
	return 0;
}